package edu.ustb.aur.controller;

import com.alibaba.fastjson.JSONObject;
import edu.ustb.aur.assetpackage.Asset;
import edu.ustb.aur.assetpackage.AssetService;
import edu.ustb.aur.chain.Chain;
import edu.ustb.aur.chain.ChainService;
import edu.ustb.aur.chain.interactive.ChainInteractiveService;
import edu.ustb.aur.moldpackage.AbstractMold;
import edu.ustb.aur.myenum.ResultCodeEnum;
import edu.ustb.aur.myenum.RightEnum;
import edu.ustb.aur.result.Result;
import edu.ustb.aur.userpackage.UserService;
import edu.ustb.aur.vo.CarControllerVo;
import edu.ustb.shellchainapi.shellchain.command.ShellChainException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;

/**
 * @author ShiZhe
 * @create 2021-11-15 14:52
 * carMold与前端car合约交互
 */
@Api(tags = "CarMold控制器")
@RestController
@RequestMapping("carMold")
@CrossOrigin
public class CarController {

    /**
     * 链类存储服务
     */
    @Autowired
    private ChainService chainService;

    /**
     * 资产链
     */
    @Autowired
    private ChainInteractiveService chainInteractiveServiceAsset = new ChainInteractiveService("OBJ");

    /**
     * 资产类存储服务
     */
    @Autowired
    private AssetService assetService;

    /**
     * 用户类存储服务
     */
    @Autowired
    private UserService userService;

    /**
     * 添加日志对象
     */
    private Logger log = LoggerFactory.getLogger(getClass());

    /**
     * 售卖操作
     *
     * 根据carControllerVo的属性修改对应用户的资产列表；
     * 根据资产的价值属性和用户收益权所占的百分比进行用户余额的转入与转出；
     * 以上所有操作成功才ok
     *
     * @param assetId         资产对象与权利对象的映射hashMap
     * @param carControllerVo 调用此操作的同意者数组，此操作执行成功后，接收者的分配rightMap，新资产价值
     * @return Result
     */
    @ApiOperation(value = "sell", notes = "售卖操作")
    @PostMapping("sell/{assetId}")
//    @Transactional
    public Result sell(@ApiParam(name = "assetId", value = "资产ID", required = true) @PathVariable String assetId,
                       @ApiParam(name = "carControllerVo", value = "输入调用此操作的同意者数组和此操作执行成功后，接收者的分配rightMap，其余为null", required = true) @RequestBody CarControllerVo carControllerVo) throws ShellChainException {


        // 新建上链的hashMap
        HashMap<String, Object> attributes = new HashMap<>();

        // 将合约id放入hashMap，上链
        attributes.put("contractId", carControllerVo.getContractId());

        // 将合约名放入hashMap，上链
        attributes.put("contractName", carControllerVo.getContractName());

        // 将操作的资产id放入hashMap，上链
        attributes.put("assetId", assetId);
        System.out.println("执行售卖操作的资产地址是：" + assetId);

        // 资产原始权利映射
        AbstractMold mold = assetService.findMold(assetId);

        //测试专用，此处输出资产原始权利映射结果，也就是mold内容，标志已经成功接收数据并正常运行
        log.info(JSONObject.toJSONString(mold));

        // 将未改变的mold放入hashMap，上链
        attributes.put("beforeState", JSONObject.toJSONString(mold));

        HashMap<String, Double> fromsRightMap = new HashMap<String, Double>(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap.size());
        fromsRightMap.putAll(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap);

        // 获取资产实体类
        Asset asset = assetService.findAsset(assetId);

        //测试专用，通过findAsset成功查找到目标资产，进行标准输出
        log.info(JSONObject.toJSONString(asset));

        if (mold.sell(mold.getMoldMap(), carControllerVo.getFroms(), carControllerVo.getToRightMap())) {

            // 资金转出
            for (String to : carControllerVo.getToRightMap().keySet()) {
                boolean out = userService.transferOut(to,
                        asset.getAssetValue() * carControllerVo.getToRightMap().get(to));
                if (!out){
                    return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
                }
            }

            // 资金转入，用户列表删除资产
            for (String from : fromsRightMap.keySet()) {
                userService.transferIn(from, asset.getAssetValue() * fromsRightMap.get(from));
                userService.deleteAssetList(from, assetId);
            }

            // 用户列表增加资产
            for (String to : carControllerVo.getToRightMap().keySet()) {
                userService.addAssetList(to, assetId);
            }

            // 测试专用：此时输出进行资产删除增加后两组用户的资产持有情况，此处暂时搁置

            // 更新资产
            asset.setAssetMold(JSONObject.toJSONString(mold));

            // 将改变了的mold放入hashMap，上链
            attributes.put("afterState", JSONObject.toJSONString(mold));

            // 更新资产
            boolean b = assetService.updateAsset(asset);

            if (b) {
                // 获取链交易id
                String txId = chainInteractiveServiceAsset.sendToChain("18XEZTrTtqQVfDxVafcJoBd37xrtcBvH4Cs4yV", 0, attributes);

                // 测试专用，上链得到交易ID
                log.info("对资产的操作完成，对用户资金的流入流出操作完成，上链后得到的交易id为：" + txId);

                // chain实体类
                boolean contractIdIsExist = chainService.findContractIdIsExist(carControllerVo.getContractId());
                if (contractIdIsExist) {
                    chainService.addContractTxIdList(carControllerVo.getContractId(), txId);
                } else {
                    Chain chain = new Chain();
                    chain.setContractId(carControllerVo.getContractId());
                    chain.setContractName(carControllerVo.getContractName());
                    ArrayList<String> contractTxIdList = new ArrayList<>();
                    contractTxIdList.add(txId);
                    chain.setContractTxIdList(contractTxIdList);
                    chainService.createChain(chain);
                }
                return Result.ok();
            } else {
                return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
            }
        } else {
            log.error("该用户组无权对该资产进行操作");
            return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
        }
    }

    /**
     * 租赁操作
     *
     * @param assetId         资产对象与权利对象的映射hashMap
     * @param carControllerVo 调用此操作的同意者数组，此操作执行成功后，接收者的分配rightMap，新资产价值
     * @return Result
     */
    @ApiOperation(value = "lease", notes = "租赁操作")
    @PostMapping("lease/{assetId}")
//    @Transactional
    public Result lease(@ApiParam(name = "assetId", value = "资产ID", required = true) @PathVariable String assetId,
                        @ApiParam(name = "carControllerVo", value = "输入调用此操作的同意者数组、租金和此操作执行成功后，接收者的分配rightMap(也就是租车的人)，其余为null", required = true) @RequestBody CarControllerVo carControllerVo) throws ShellChainException {

        // 新建上链的hashMap
        HashMap<String, Object> attributes = new HashMap<>();

        // 将合约id放入hashMap，上链
        attributes.put("contractId", carControllerVo.getContractId());

        // 将合约名放入hashMap，上链
        attributes.put("contractName", carControllerVo.getContractName());

        // 将操作的资产id放入hashMap，上链
        attributes.put("assetId", assetId);
        System.out.println("执行租赁操作的资产地址是：" + assetId);

        // 资产原始权利映射
        AbstractMold mold = assetService.findMold(assetId);

        // 将为改变的mold放入hashMap，上链
        attributes.put("beforeState", JSONObject.toJSONString(mold));

        HashMap<String, Double> fromsRightMap = new HashMap<String, Double>(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap.size());
        fromsRightMap.putAll(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap);

        // 获取资产实体类
        Asset asset = assetService.findAsset(assetId);

        if (mold.lease(mold.getMoldMap(), carControllerVo.getFroms(), carControllerVo.getToRightMap())) {

            //资金转出
            for (String to : carControllerVo.getToRightMap().keySet()) {
                boolean out = userService.transferOut(to, carControllerVo.getRent() * carControllerVo.getToRightMap().get(to));
                if (!out){
                    return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
                }
            }

            //资金转入
            for (String from : fromsRightMap.keySet()) {
                userService.transferIn(from, carControllerVo.getRent() * fromsRightMap.get(from));
            }

            //用户列表增加资产
            for (String to : carControllerVo.getToRightMap().keySet()) {
                userService.addAssetList(to, assetId);
            }

            //更新资产
            asset.setAssetMold(JSONObject.toJSONString(mold));

            // 将改变了的mold放入hashMap，上链
            attributes.put("afterState", JSONObject.toJSONString(mold));

            boolean b = assetService.updateAsset(asset);
            if (b) {
                // 获取链交易id
                String txId = chainInteractiveServiceAsset.sendToChain("18XEZTrTtqQVfDxVafcJoBd37xrtcBvH4Cs4yV", 0, attributes);

                // 测试专用，上链得到交易ID
                log.info("对资产的操作完成，对用户资金的流入流出操作完成，上链后得到的交易id为：" + txId);

                // chain实体类
                boolean contractIdIsExist = chainService.findContractIdIsExist(carControllerVo.getContractId());
                if (contractIdIsExist) {
                    chainService.addContractTxIdList(carControllerVo.getContractId(), txId);
                } else {
                    Chain chain = new Chain();
                    chain.setContractId(carControllerVo.getContractId());
                    chain.setContractName(carControllerVo.getContractName());
                    ArrayList<String> contractTxIdList = new ArrayList<>();
                    contractTxIdList.add(txId);
                    chain.setContractTxIdList(contractTxIdList);
                    chainService.createChain(chain);
                }
                return Result.ok();
            } else {
                return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
            }
        } else {
            return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
        }
    }

    /**
     * 租赁返还操作
     *
     * @param assetId         资产对象与权利对象的映射hashMap
     * @param carControllerVo 调用此操作的同意者数组，此操作执行成功后，接收者的分配rightMap，新资产价值
     * @return Result
     */
    @ApiOperation(value = "leaseReturn", notes = "租赁返还操作")
    @PostMapping("leaseReturn/{assetId}")
//    @Transactional
    public Result leaseReturn(@ApiParam(name = "assetId", value = "资产ID", required = true) @PathVariable String assetId,
                        @ApiParam(name = "carControllerVo", value = "输入调用此操作的同意者数组、租金和此操作执行成功后，接收者的分配rightMap(也就是租车的人)，其余为null", required = true) @RequestBody CarControllerVo carControllerVo) throws ShellChainException {

        // 新建上链的hashMap
        HashMap<String, Object> attributes = new HashMap<>();

        // 将合约id放入hashMap，上链
        attributes.put("contractId", carControllerVo.getContractId());

        // 将合约名放入hashMap，上链
        attributes.put("contractName", carControllerVo.getContractName());

        // 将操作的资产id放入hashMap，上链
        attributes.put("assetId", assetId);
        System.out.println("执行租赁返回的资产地址是：" + assetId);

        // 资产原始权利映射
        AbstractMold mold = assetService.findMold(assetId);

        // 将未改变的mold放入hashMap，上链
        attributes.put("beforeState", JSONObject.toJSONString(mold));

        HashMap<String, Double> fromsRightMap = new HashMap<String, Double>(mold.getMoldMap().get(RightEnum.USE_RIGHT).rightMap.size());
        fromsRightMap.putAll(mold.getMoldMap().get(RightEnum.USE_RIGHT).rightMap);

        // 获取资产实体类
        Asset asset = assetService.findAsset(assetId);

        if (mold.leaseReturn(mold.getMoldMap(), carControllerVo.getFroms(), carControllerVo.getToRightMap())) {

            //用户列表删除资产
            for (String from : fromsRightMap.keySet()) {
                userService.deleteAssetList(from, assetId);
            }

            //更新资产
            asset.setAssetMold(JSONObject.toJSONString(mold));

            // 将改变了的mold放入hashMap，上链
            attributes.put("afterState", JSONObject.toJSONString(mold));

            boolean b = assetService.updateAsset(asset);
            if (b) {
                // 获取链交易id
                String txId = chainInteractiveServiceAsset.sendToChain("18XEZTrTtqQVfDxVafcJoBd37xrtcBvH4Cs4yV", 0, attributes);

                // 测试专用，上链得到交易ID
                log.info("对资产的操作完成，对用户资金的流入流出操作完成，上链后得到的交易id为：" + txId);

                // chain实体类
                boolean contractIdIsExist = chainService.findContractIdIsExist(carControllerVo.getContractId());
                if (contractIdIsExist) {
                    chainService.addContractTxIdList(carControllerVo.getContractId(), txId);
                } else {
                    Chain chain = new Chain();
                    chain.setContractId(carControllerVo.getContractId());
                    chain.setContractName(carControllerVo.getContractName());
                    ArrayList<String> contractTxIdList = new ArrayList<>();
                    contractTxIdList.add(txId);
                    chain.setContractTxIdList(contractTxIdList);
                    chainService.createChain(chain);
                }
                return Result.ok();
            } else {
                return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
            }
        } else {
            return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
        }
    }

    /**
     * 抵押操作
     *
     * @param assetId         资产对象与权利对象的映射hashMap
     * @param carControllerVo 调用此操作的同意者数组，此操作执行成功后，接收者的分配rightMap，新资产价值
     * @return Result
     */
    @ApiOperation(value = "mortgage", notes = "抵押操作")
    @PostMapping("mortgage/{assetId}")
//    @Transactional
    public Result mortgage(@ApiParam(name = "assetId", value = "资产ID", required = true) @PathVariable String assetId,
                           @ApiParam(name = "carControllerVo", value = "输入调用此操作的同意者数组和此操作执行成功后，接收者的分配rightMap，其余为null", required = true) @RequestBody CarControllerVo carControllerVo) throws ShellChainException {

        // 新建上链的hashMap
        HashMap<String, Object> attributes = new HashMap<>();

        // 将合约id放入hashMap，上链
        attributes.put("contractId", carControllerVo.getContractId());

        // 将合约名放入hashMap，上链
        attributes.put("contractName", carControllerVo.getContractName());

        // 将操作的资产id放入hashMap，上链
        attributes.put("assetId", assetId);
        System.out.println("执行抵押操作的资产地址是：" + assetId);

        // 资产原始权利映射
        AbstractMold mold = assetService.findMold(assetId);

        // 将为改变的mold放入hashMap，上链
        attributes.put("beforeState", JSONObject.toJSONString(mold));

        HashMap<String, Double> fromsRightMap = new HashMap<String, Double>(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap.size());
        fromsRightMap.putAll(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap);

        // 获取资产实体类
        Asset asset = assetService.findAsset(assetId);

        if (mold.mortgage(mold.getMoldMap(), carControllerVo.getFroms(), carControllerVo.getToRightMap())) {

            //资金转出
            for (String to : carControllerVo.getToRightMap().keySet()) {
                boolean out = userService.transferOut(to, carControllerVo.getLoan() * carControllerVo.getToRightMap().get(to));
                if (!out){
                    return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
                }
            }

            //资金转入
            for (String from : fromsRightMap.keySet()) {
                userService.transferIn(from, carControllerVo.getLoan() * fromsRightMap.get(from));
            }

            //用户列表增加资产
            for (String to : carControllerVo.getToRightMap().keySet()) {
                userService.addAssetList(to, assetId);
            }

            //更新资产
            asset.setAssetMold(JSONObject.toJSONString(mold));

            // 将改变了的mold放入hashMap，上链
            attributes.put("afterState", JSONObject.toJSONString(mold));

            boolean b = assetService.updateAsset(asset);
            if (b) {
                // 获取链交易id
                String txId = chainInteractiveServiceAsset.sendToChain("18XEZTrTtqQVfDxVafcJoBd37xrtcBvH4Cs4yV", 0, attributes);

                // chain实体类
                boolean contractIdIsExist = chainService.findContractIdIsExist(carControllerVo.getContractId());
                if (contractIdIsExist) {
                    chainService.addContractTxIdList(carControllerVo.getContractId(), txId);
                } else {
                    Chain chain = new Chain();
                    chain.setContractId(carControllerVo.getContractId());
                    chain.setContractName(carControllerVo.getContractName());
                    ArrayList<String> contractTxIdList = new ArrayList<>();
                    contractTxIdList.add(txId);
                    chain.setContractTxIdList(contractTxIdList);
                    chainService.createChain(chain);
                }
                return Result.ok();
            } else {
                return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
            }
        } else {
            return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
        }
    }

    /**
     * 抵押赎回操作
     *
     * @param assetId         资产对象与权利对象的映射hashMap
     * @param carControllerVo 调用此操作的同意者数组，此操作执行成功后，接收者的分配rightMap，新资产价值
     * @return Result
     */
    @ApiOperation(value = "mortgage", notes = "抵押操作")
    @PostMapping("mortgageReturn/{assetId}")
//    @Transactional
    public Result mortgageReturn(@ApiParam(name = "assetId", value = "资产ID", required = true) @PathVariable String assetId,
                           @ApiParam(name = "carControllerVo", value = "输入调用此操作的同意者数组和此操作执行成功后，接收者的分配rightMap，其余为null", required = true) @RequestBody CarControllerVo carControllerVo) throws ShellChainException {

        // 新建上链的hashMap
        HashMap<String, Object> attributes = new HashMap<>();

        // 将合约id放入hashMap，上链
        attributes.put("contractId", carControllerVo.getContractId());

        // 将合约名放入hashMap，上链
        attributes.put("contractName", carControllerVo.getContractName());

        // 将操作的资产id放入hashMap，上链
        attributes.put("assetId", assetId);
        System.out.println("执行抵押赎回操作的资产地址是：" + assetId);

        // 资产原始权利映射
        AbstractMold mold = assetService.findMold(assetId);

        // 将为改变的mold放入hashMap，上链
        attributes.put("beforeState", JSONObject.toJSONString(mold));

        HashMap<String, Double> fromsRightMap = new HashMap<String, Double>(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap.size());
        fromsRightMap.putAll(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap);

        // 获取资产实体类
        Asset asset = assetService.findAsset(assetId);

        if (mold.mortgage(mold.getMoldMap(), carControllerVo.getFroms(), carControllerVo.getToRightMap())) {

            //资金转出
            for (String to : carControllerVo.getToRightMap().keySet()) {
                boolean out = userService.transferOut(to, carControllerVo.getRepayment() * carControllerVo.getToRightMap().get(to));
                if (!out){
                    return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
                }
            }

            //资金转入
            for (String from : fromsRightMap.keySet()) {
                userService.transferIn(from, carControllerVo.getRepayment() * fromsRightMap.get(from));
            }

            //用户列表删除资产
            for (String from : fromsRightMap.keySet()) {
                userService.deleteAssetList(from, assetId);
            }

            //更新资产
            asset.setAssetMold(JSONObject.toJSONString(mold));

            // 将改变了的mold放入hashMap，上链
            attributes.put("afterState", JSONObject.toJSONString(mold));

            boolean b = assetService.updateAsset(asset);
            if (b) {
                // 获取链交易id
                String txId = chainInteractiveServiceAsset.sendToChain("18XEZTrTtqQVfDxVafcJoBd37xrtcBvH4Cs4yV", 0, attributes);

                // chain实体类
                boolean contractIdIsExist = chainService.findContractIdIsExist(carControllerVo.getContractId());
                if (contractIdIsExist) {
                    chainService.addContractTxIdList(carControllerVo.getContractId(), txId);
                } else {
                    Chain chain = new Chain();
                    chain.setContractId(carControllerVo.getContractId());
                    chain.setContractName(carControllerVo.getContractName());
                    ArrayList<String> contractTxIdList = new ArrayList<>();
                    contractTxIdList.add(txId);
                    chain.setContractTxIdList(contractTxIdList);
                    chainService.createChain(chain);
                }
                return Result.ok();
            } else {
                return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
            }
        } else {
            return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
        }
    }

    /**
     * 馈赠操作
     *
     * @param assetId         资产对象与权利对象的映射hashMap
     * @param carControllerVo 调用此操作的同意者数组，此操作执行成功后，接收者的分配rightMap，新资产价值
     * @return Result
     */
    @ApiOperation(value = "gift", notes = "馈赠操作")
    @PostMapping("gift/{assetId}")
//    @Transactional
    public Result gift(@ApiParam(name = "assetId", value = "资产ID", required = true) @PathVariable String assetId,
                       @ApiParam(name = "carControllerVo", value = "输入调用此操作的同意者数组和此操作执行成功后，接收者的分配rightMap，其余为null", required = true) @RequestBody CarControllerVo carControllerVo) throws ShellChainException {

        // 新建上链的hashMap
        HashMap<String, Object> attributes = new HashMap<>();

        // 将合约id放入hashMap，上链
        attributes.put("contractId", carControllerVo.getContractId());

        // 将合约名放入hashMap，上链
        attributes.put("contractName", carControllerVo.getContractName());

        // 将操作的资产id放入hashMap，上链
        attributes.put("assetId", assetId);
        System.out.println("执行馈赠操作的资产地址是：" + assetId);

        // 资产原始权利映射
        AbstractMold mold = assetService.findMold(assetId);

        // 将为改变的mold放入hashMap，上链
        attributes.put("beforeState", JSONObject.toJSONString(mold));

        HashMap<String, Double> fromsRightMap = new HashMap<String, Double>(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap.size());
        fromsRightMap.putAll(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap);

        // 获取资产实体类
        Asset asset = assetService.findAsset(assetId);

        if (mold.gift(mold.getMoldMap(), carControllerVo.getFroms(), carControllerVo.getToRightMap())) {

            //用户列表删除资产
            for (String from : fromsRightMap.keySet()) {
                userService.deleteAssetList(from, assetId);
            }

            //用户列表增加资产
            for (String to : carControllerVo.getToRightMap().keySet()) {
                userService.addAssetList(to, assetId);
            }

            //更新资产
            asset.setAssetMold(JSONObject.toJSONString(mold));

            // 将改变了的mold放入hashMap，上链
            attributes.put("afterState", JSONObject.toJSONString(mold));

            boolean b = assetService.updateAsset(asset);
            if (b) {
                // 获取链交易id
                String txId = chainInteractiveServiceAsset.sendToChain("18XEZTrTtqQVfDxVafcJoBd37xrtcBvH4Cs4yV", 0, attributes);

                // chain实体类
                boolean contractIdIsExist = chainService.findContractIdIsExist(carControllerVo.getContractId());
                if (contractIdIsExist) {
                    chainService.addContractTxIdList(carControllerVo.getContractId(), txId);
                } else {
                    Chain chain = new Chain();
                    chain.setContractId(carControllerVo.getContractId());
                    chain.setContractName(carControllerVo.getContractName());
                    ArrayList<String> contractTxIdList = new ArrayList<>();
                    contractTxIdList.add(txId);
                    chain.setContractTxIdList(contractTxIdList);
                    chainService.createChain(chain);
                }
                return Result.ok();
            } else {
                return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
            }
        } else {
            return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
        }
    }

    /**
     * 销毁操作
     *
     * @param assetId         资产对象与权利对象的映射hashMap
     * @param carControllerVo 调用此操作的同意者数组，此操作执行成功后，接收者的分配rightMap，新资产价值
     * @return Result
     */
    @ApiOperation(value = "destroy", notes = "销毁操作")
    @DeleteMapping("destroy/{assetId}")
//    @Transactional
    public Result destroy(@ApiParam(name = "assetId", value = "资产ID", required = true) @PathVariable String assetId,
                          @ApiParam(name = "carControllerVo", value = "调用此操作的同意者数组，其余为null", required = true) @RequestBody CarControllerVo carControllerVo) throws ShellChainException {

        // 新建上链的hashMap
        HashMap<String, Object> attributes = new HashMap<>();

        // 将合约id放入hashMap，上链
        attributes.put("contractId", carControllerVo.getContractId());

        // 将合约名放入hashMap，上链
        attributes.put("contractName", carControllerVo.getContractName());

        // 将操作的资产id放入hashMap，上链
        attributes.put("assetId", assetId);
        System.out.println("执行销毁操作的资产地址是：" + assetId);

        // 资产原始权利映射
        AbstractMold mold = assetService.findMold(assetId);

        // 将为改变的mold放入hashMap，上链
        attributes.put("beforeState", JSONObject.toJSONString(mold));

        HashMap<String, Double> fromsRightMap = new HashMap<String, Double>(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap.size());
        fromsRightMap.putAll(mold.getMoldMap().get(RightEnum.USUFRUCT_RIGHT).rightMap);

        // 获取资产实体类
        Asset asset = assetService.findAsset(assetId);

        if (mold.destroy(mold.getMoldMap(), carControllerVo.getFroms())) {

            //用户列表删除资产
            for (String from : fromsRightMap.keySet()) {
                userService.deleteAssetList(from, assetId);
            }

            //更新资产
            asset.setAssetMold(JSONObject.toJSONString(mold));

            assetService.updateAsset(asset);

            // 将改变了的mold放入hashMap，上链
            attributes.put("afterState", JSONObject.toJSONString(mold));

            //删除资产
            boolean b = assetService.deleteAsset(assetId);

            if (b) {
                // 获取链交易id
                String txId = chainInteractiveServiceAsset.sendToChain("18XEZTrTtqQVfDxVafcJoBd37xrtcBvH4Cs4yV", 0, attributes);

                // chain实体类
                boolean contractIdIsExist = chainService.findContractIdIsExist(carControllerVo.getContractId());
                if (contractIdIsExist) {
                    chainService.addContractTxIdList(carControllerVo.getContractId(), txId);
                } else {
                    Chain chain = new Chain();
                    chain.setContractId(carControllerVo.getContractId());
                    chain.setContractName(carControllerVo.getContractName());
                    ArrayList<String> contractTxIdList = new ArrayList<>();
                    contractTxIdList.add(txId);
                    chain.setContractTxIdList(contractTxIdList);
                    chainService.createChain(chain);
                }
                return Result.ok();
            } else {
                return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
            }
        } else {
            return Result.fail(Result.build(mold, ResultCodeEnum.FAIL));
        }
    }

    /**
     * 更新资产价值操作
     *
     * @param assetId         资产id
     * @param carControllerVo 包括合约id，合约名和新的资产对象，其中新的资产对象不包括资产id
     * @return Result
     */
    @ApiOperation(value = "update", notes = "更新资产操作")
    @PostMapping("update/{assetId}")
    public Result update(@ApiParam(name = "assetId", value = "资产ID", required = true) @PathVariable String assetId,
                         @ApiParam(name = "carControllerVo", value = "调用此操作的同意者数组，其余为null", required = true) @RequestBody CarControllerVo carControllerVo) throws ShellChainException {



        Asset assetNew = carControllerVo.getAssetNew();
        System.out.println(assetNew);




        // 新建上链的hashMap
        HashMap<String, Object> attributes = new HashMap<>();

        // 将合约id放入hashMap，上链
        attributes.put("contractId", carControllerVo.getContractId());

        // 将合约名放入hashMap，上链
        attributes.put("contractName", carControllerVo.getContractName());

        // 将资产对象放入hashMap，上链
        attributes.put("assetId", assetId);

        // 资产原始权利映射
        AbstractMold moldOld = assetService.findMold(assetId);

        // 将未改变的mold放入hashMap，上链
        attributes.put("beforeState", JSONObject.toJSONString(moldOld));

        // 将资产ID与新的资产对象绑定
        assetNew.setAssetId(assetId);

        if (moldOld.update(assetId, carControllerVo.getFroms(), assetNew, moldOld.getMoldMap())) {
            log.info("该用户组有权对该资产进行操作");

            // 删除旧的用户列表中资产ID
            Set<RightEnum> rightEnumsOld = moldOld.getMoldMap().keySet();
            for (RightEnum rightEnum :rightEnumsOld) {
                HashMap<String, Double> fromsRightMap = new HashMap<String, Double>(moldOld.getMoldMap()
                        .get(rightEnum).rightMap.size());
                fromsRightMap.putAll(moldOld.getMoldMap().get(rightEnum).rightMap);
                for (String from : fromsRightMap.keySet()) {
                    userService.deleteAssetList(from, assetId);
                }
            }

            // 调用AssetService里的updateAsset方法，对资产进行更新
            boolean b = assetService.updateAsset(assetNew);

            // 资产原始权利映射
            AbstractMold moldNew = assetService.findMold(assetId);

            // 添加新的用户列表中资产ID
            Set<RightEnum> rightEnumsNew = moldNew.getMoldMap().keySet();
            for (RightEnum rightEnum :rightEnumsNew) {
                HashMap<String, Double> fromsRightMap = new HashMap<String, Double>(moldNew.getMoldMap()
                        .get(rightEnum).rightMap.size());
                fromsRightMap.putAll(moldNew.getMoldMap().get(rightEnum).rightMap);
                for (String from : fromsRightMap.keySet()) {
                    userService.addAssetList(from, assetId);
                }
            }

            // 将改变了的mold放入hashMap，上链
            attributes.put("afterState", JSONObject.toJSONString(moldNew));

            if (b) {
                // 获取链交易id
                String txId = chainInteractiveServiceAsset.sendToChain("18XEZTrTtqQVfDxVafcJoBd37xrtcBvH4Cs4yV", 0, attributes);

                // 测试专用，上链得到交易ID
                log.info("对资产的更新操作完成，上链后得到的交易id为：" + txId);

                // chain实体类
                boolean contractIdIsExist = chainService.findContractIdIsExist(carControllerVo.getContractId());
                if (contractIdIsExist) {
                    chainService.addContractTxIdList(carControllerVo.getContractId(), txId);
                } else {
                    Chain chain = new Chain();
                    chain.setContractId(carControllerVo.getContractId());
                    chain.setContractName(carControllerVo.getContractName());
                    ArrayList<String> contractTxIdList = new ArrayList<>();
                    contractTxIdList.add(txId);
                    chain.setContractTxIdList(contractTxIdList);
                    chainService.createChain(chain);
                }
                return Result.ok();
            } else {
                return Result.fail(Result.build(moldNew, ResultCodeEnum.FAIL));
            }
        } else {
            log.error("该用户组无权对该资产进行操作");
            return Result.fail(Result.build(assetNew.getAssetMold(), ResultCodeEnum.FAIL));
        }
    }
}
